Dave,
my original answer was for virtual directories, please ignore it.
1. one of the weaknesses of the module deployment module is that modules get their own folder structure under desktopmodules i.e. desktopmodules/module1 and desktopmodules/module2. There is no shared location for common code, this is something we're looking at for an upcoming version - the ability to share common code, and correctly version it. However, there are a number of workarounds. The first is to simply create a class library, and put the code in there, and then to add that dll to each module. The second is a bit of a hack, but you can implement the IUpgradeable interface in your modules, and use it to perform post install items i.e. it runs the first time after install so you could move code to a common location.
2. similar to above, create a class library and use it to host your custom server controls or else move your controls to a common location such as an app_code folder via IUpgradeable.
Finally, you could also consider using the xmlmerge capabilities to add/amend entries to your web.config (http://www.dotnetnuke.com/Community/Blogs/tabid/825/EntryID/1844/Default.aspx). These could then allow for additional probing directories (for dll's), or add handlers to support common functionality -look at the default web.config to see how this is used to generate captcha images and support rss feeds etc.
Please note, if you plan to always install modules together, you can deploy multiple items within one module, take a look at the blog module and you'll see it add's a number of modules at the same time to support linked, but optional functions. As the deployment happens in one go, it's easy to add a file containing utility functions.
Cathal