What software do exchanges use to manage wallets? Do they write wrappers around bitcoind or is there a better solution out there? Some exchanges handle dozens of digital currencies, does this mean they are running bitcoind, litecoind, dogecoind, etc concurrently?
From an exchange's perspective, the best option would be to write mostly your own software. From a technical perspective, an exchange only has to fulfill the following in order to be accepting a crypto-currency:


Must allow deposits of Bitcoin or coin the exchange claims to accept.
Must allow withdraws of Bitcoin or coin the exchange claims to accept.


Normally bitcoind or the altcoin variant of it, litecoind, dogecoind, etc., take care of both for a user of a crypto-currency. But an exchange has special demands. Here are some issues I can think of that may happen to an exchange if they used the core client.


Core clients are not designed to work in a multiple server environments, something vital for large exchanges.
Private keys and corresponding addresses need to be stored under special conditions. An exchange may want add a username along with an address or even reuse addresses for efficiency.
Core clients aren't exactly lightweight. An exchange doesn't need a lot of features commonly packaged together with a core client. As an example, accounts; it's purely for organizing money cosmetically, something exchanges don't need.
Core clients don't allow for more intricate control of transactions or other components, SatoshiDice is impossible to create using bitcoind because it require manipulation of transaction inputs to create sends, something you can't currently do with bitcoind.


So what should an exchange be doing?

Using a combination of the two, or even ditching the core client. There are many programming libraries that simplify all aspects of Bitcoin technology, libbitcoin is a C++ library that allows you to make a partial or full node in no time. SatoshiDice is constructed on BitcoinJ, a popular Java library for Bitcoin. There are also many libraries available for other languages, but the point is that building a node isn't too hard.

I recommend a hybrid use because bitcoind is a lot more safe and bug-free than your own code. You can accidentally create code that creates invalid transactions or even accidentally send coins to the wrong address. I'd use a library and my favorite language to detect deposits and accredit them to accounts, and then push raw transactions to a bitcoind instance running on my own or possibly the same server where it will validate it and take care of sending it other nodes in the network. Less space to mess up in code.

For altcoins, you'd need an instance running or just doing small modifications to the code to differentiate. There isn't a huge difference between the protocols all the crypto-currencies use. You should know anyways if you're planning to accept a coin as an exchange.

TL;DR

Exchanges should be using software they're wrote themselves. This isn't hard to do as there are many libraries available that give you nitty-gritty access to Bitcoin. Core clients can be a bottleneck at times but can be used in conjunction to avoid said bottlenecks while maintaining a safety net for an exchange and can even simplify certain parts.