Well, that is not an easy question to answer. The short answer is that there is no API to do what you are asking. In fact the OS isn't really designed to allow that, so some of the information required to figure it out 100% is not preserved in the kernel's object manager. In other words, you can't, not 100% anyway. Even Mark Russinovich could figure out how to make a sysinternal tool to answer the question. With that said, it is possible to figure out quite a lot about who is using what.
First off, people use devices by opening a handle to them using CreateFile. You typically pass in a device interface path that you discovered using SetupAPI, or one of the other APIs Windows has. The IO Manager will resolve the device directly, or it also has other branch points where it can involve drivers on the stack to resolve the device. Ultimately the client gets a handle to the device. I will leave it at that. The important thing to know is that devices that are being used have handles backed by objects that the kernel's object manager tracks.
Devices being used will have open handles, so you can look at the handles; however, they don't always tell you enough information of what they are for. With experience, you can recognize some types of handles, and even figure out what interfaces the match to. Still, some other handles to device, will not have that information: they can be symlinked, they could just be a named object created directly by the device driver (assuming the set the right permissions, etc.), or a lot of other reasons.
Next, are we talking about user mode or kernel mode? Drivers in KM can open handles to other devices and they will not be directly visible to a UM process. You will not be able to see a lot of the references, unless you are discovering them in KM. If you are talking about a UM tool, then the tool could open other processes in UM and enumerate their handles, assuming it has enough permissions. It would probably need TCB (trusted computing base) to open them all. The UM tool will not have visibility into the KM handles.
Do you think you could write such a tool? It would be a great way to learn how IOMGR works, and PnP. I could write one, but it still would not be 100% complete.
A good starting place to learn about this is another tool called KD (the Kenrel Debugger). Dump all of the handles in the system, and go spelunking. That will give you a lot of experience you would need to write the tool I was talking about.