The basic idea is to, try to spend 1 hour on each of: 1. examine the code very quickly (try to do it in an hour or so), and based on the scan to guess what the top 4-5 subcomponents of a system are. 2. do quick code examinations to figure out what each subcomponent is supposed to be doing, and how each subcomponent is supposed to depend on the other subcomponents. 3. Now modify the code to reflect the above components. At the simplest, just move code into new directories for each component, but at more detailed levels you can make sure that there is never any single source file that has implementation for more than one component.
Now you are done. You can clean up code more if you want, but do that slowly. Just make sure to not put new code in bad areas. Yes, you will possibly have spent more than 1 hour on each part. But you should have a much better grasp of the code, and the code will not keep on deteriorating.
I am not really talking about badly documented code or code with bad naming conventions, or other related problems. However, when the big problem is the 'spaghetti' (and cyclic dependencies) - this has really been the only solution that has worked well.