Tree shakers require that you look at every function-bound symbol and determine if that symbol appears in the call graph of the main function(s) or in an isolated call graph. The functions that follow the call graph exist in most Common Lisps but they are not standardized; they're implementation-dependent. That's part of the reason tree shakers aren't widespread. Another reason is that if you're using the compiler in your runtime, even isolated parts of the call graph can still be useful, so tree shaking becomes something of a policy decision rather than a pure algorithm.
...and just as a follow-up, once you've dug into the problem enough to discover it's surprisingly difficult to define what is "the right thing" for a tree-shaker in Lisp to do, you realize that even if you build it, it doesn't buy you much. That's why we tend to sound curmudgeonly about the issue. It's a valuable learning exercise, so feel free to dig in. You'll gain some valuable insights into what makes Lisp special.