Here are a number of differences. Some are not important, some are real important and easy to understand, some are real important and hard to understand. This list is not exhaustive.
DTD's are not namespace aware.
DTD's have #define, #include, and #ifdef -- or, less C-oriented, the ability to define shorthand abbreviations, external content, and some conditional parsing.
A DTD describes the entire XML document (even if it leaves "holes"); a schema can define portions.
XSD has a type system.
XSD has a much richer language for describing what element or attribute content "looks like." This is related to the type system.
You can put a DTD inline into an XML document, you cannot do this with XSD. This means DTD's are more secure (you only have to protect one bytestream -- the xml/dtd -- and not multiple).
The official definition of "valid XML" requires a DTD. Since this may be impractical, if not impossible, you often have to settle for schema-valid, which is not quite the same.
Rich Salz - http://www.datapower.com
In terms of validation functionality, XSD can define all the constraints that a DTD can define, and many more. To take a simple example, XSD can say that a particular attribute must be a valid date, or a number, or a list of URIs, or a string that is exactly 8 characters long. To take another example, XSD can define much richer constraints on uniqueness of values within a document.
The content of this post was shamelessly stolen from the XML-DEV mailing list archives. I wanted to capture the data to avoid loosing it to the google machine.