As I suggested earlier ... you could be faced with a well-behaved just poorly-designed program, or you could be dealing with a monster. You need to find out which one it is, first. In a word: “can all these various bits be part of the same program at the same time?”
As we all know, it’s not illegitimate for a well-designed modular program to load parts of itself dynamically. Modules like UNIVERSAL::require can do a lot to de-fang this process. However, there is a lot of old legacy-software out there which was built in the times when programs couldn’t be big. (The days of overlays and such.) These programs that couldn’t be big, also couldn’t be tested as if they were big. Fast-forward a couple of decades and guess what ... they can be big, and they’re not stable. Programs that have gone through this life-cycle are often fairly intractable.
If this program, as I somewhat suspect, “evolved,” then the first step that I would take is that very thorough present-state assessment ... and probably lobby for some overhaul work at a near-future date. These types of programs are often very unknown. (And if my comments turn out to be nonsensically off-the-mark, well, mea culpa, but they are based on some pretty painful memories of similar software.)