(sorry if any of this comes across as condescending, I'm not sure what your knowledge level is on the topic)
Link-time optimization does something like this, but only after all the code has been compiled. You can then have a look at the complete program, and drop everything from it that isn't either re-exported or used.
The other thing is that the compiler doesn't normally look at dependencies at all, since they've already been compiled. Almost all of the time when you're using dependencies or writing a program, you're creating a dynamically linked executable. Dependencies are imported as shared libraries, which means they've already been compiled in a format that you can load. During compilation, a linker looks at the dependencies you're loading, and fixes up addresses for symbols. You're not paying a compilation cost for unused symbols in the shared libraries, and the dynamic linker takes care of loading the relevant dependency when you execute your program.
When you're writing a statically linked executable, library code is copied into your executable during linking (so, "static" linking). If you've enabled LTO, you only get code that you're actually using. However, the code you're copying from the dependency has already been compiled, and so you're not paying compilation cost for dependencies in this case as well.
Long story short, in most of the cases, the compiler only spends time compiling your code. Dependencies are either included in a binary format by the linker in case of a static executable (where only stuff you're actually using is included) or alle required symbols are massaged by the linker so the dynamic linker can make them available from a common shared library when the program is executed.
This is only for boring old compiled programs, I don't exactly know how languages like Java or Python do this.
(P.S.: And it doesn't make sense to optimize shared libraries by dropping unused symbols, because any new program might use the symbols you've dropped. Some system like Nix could probably look at all the programs you've installed, and collect a set of symbols needed for the shared library, and only include those, but that seems like a lot of effort. Also, it's very hard to cache, as there'd suddenly be 2^(number of symbols in library) possible versions of each library depending on what symbols you need.)