Per my comment above, I've been trying to think about how best to achieve the same thing: introducing radical modularity into my models. I tried a few ways of precisely linking subsets of vertices across multiple objects with Hooks, Constraints, Vertex Parenting, etc, and found them all to be insufficiently flexible, and generally just very clearly not designed to achieve the intended goal. I even invested considerable time taking a mesh with one shape (a MakeHuman human head) and tediously building a ShapeKey that could deform it into an entirely different shape (a lion head -- the one you see below in this answer); that actually works quite well in some ways (you won't get unexpected splits when fitting an Armature to it!), but it also is severely limited in other ways that I found unacceptable (building an incredibly complex ShapeKey that would take hours to re-build forces you to avoid adding new Loop Cuts and similar edits that can alter the topological assumptions the ShapeKey has made, for example).
I hadn't come up with a good solution yet, but reading your question got me thinking: why not drop the requirement that the two objects be separate, and use a Mask to control which head is visible? With this approach, in principle you should have full control using standard Armatures / Mesh Deforms as you'd normally like, and there should be no risk of meshes splitting in unexpected ways.
Here's a very crude first shot at this, which I think basically serves as a strong proof-of-concept that this can work...
First, I'll use this stylized female character I've been working on, and I'm going to set her up to switch between a lion(-lady?) & human-lady head:

Second, I have to join the two objects, of course. Here is what they look like in Rendered View (note that things will be rather ugly throughout this, as I'm not cleaning anything up, including making no attempt to make Materials consistent), where you can clearly see that she's got two heads:

Third, I'll add a Pitchipoy rig (from which I'll use a single bone as an example), make sure the two heads are both joined to the same edge loop, and start selecting the vertices I need to make four vertex groups (Lion Head, Lady Head, Lion, and Lady, where Lion is the Inverse-Select of Lady Head, and similarly Lady is the Inverse-Select of Lion Head):

Fourth, just to illustrate how this should work, I'll assign all the vertices in both Lion Head and Lady Head to spine.004 from the Pitchipoy model, to verify that there's no unexpected breaking of the meshes etc. Here, we see we can turn the Lion Head & Lady Heads simultaneously using the relevant bone in pose mode:

Fifth, I'll just check that it turns in the opposite direction, too. Nothing unexpected here:

Sixth and seventh, we'll now check that we can do similar rotations, but with our Mask modifier choosing whether to show Lion or Lady:


Lastly, here's just an illustration of what the Lion vertex group looks like, visually (and Lady is analogous, of course):

In short, I think this provides a workable flow for using standard tools (Armatures/Mesh Deform, notably) to deform a single mesh that has multiple heads (or other limbs).
However, a few caveats/issues I haven't explored or that need more attention:
- I may have been moving a bit too quickly (maybe I had one of the two heads hidden at the time of weighting), so I'll go back and doublecheck this and update my answer, but in my crude test automatic weight assignment for the Armature seemed to get quite confused and only to apply weights to one of the two heads at a time. If this is the case, it should be possible to work around it by fitting each model separately before combining the models and their vertex group weights, I think, but that would certainly be an unwelcome complication (EDIT: On further tests I am unable to replicate this problematic behavior; standard Armature parenting/automatic weighting seems to work just fine on the multi-headed mesh. I don't want to delete this bullet point just yet, though, as -- being unable to replicate it -- I do not yet understand why my original Armature-parenting failed.)
- In this test case, I was able to use Mask to select an entire character at once by just inverting the part of the model (whichever head) I did not want. This logic doesn't extend to the case where multiple limbs can be combined in modular fashion, though, or even just where there are more than two heads. I think a combination of Vertex Weight Edit/Vertex Weight Mix modifiers and more modular vertex groups (one on each torso, one on each head, etc) could overcome this (and, failing that, it could certainly be overcome with a custom Python script)
- Stuffing everything into a single object like this overcomes the issues you asked about, but severely limits the options Blender provides for organizing your model. You won't be able to move the Lion Head and Lady Head (or Lion / Lady, of course) into separate collections, since they're part of the same object, and if you pursue this far enough, the single model could become so complex that you (or your CPU/GPU, more to the point!) would never want to display all its vertices at once. You'll mostly be limited to Vertex Groups for documenting/organizing what would normally be treated as separate Objects/Collections, and limited to using tools like Mask to avoid displaying too much of the overall mesh data at once
A modular workflow like this stuffed all into one model can make for an enormously complicated single model, so I'm sure there's more to be discovered about when/where it has limitations, but from what I can tell this is a reasonably flexible starting point for achieving the desired effect without troublesome splitting of the modular sub-components of the overall object/character.