Вероятно, самый простой подход - использовать такой инструмент, как yGuard, который "... обеспечивает сложную функциональность сжатия кода посредством анализа зависимостей". Это также решит ту же проблему, когда вы зададите ему точку входа, и она выполнит анализ зависимостей, чтобы определить, какие классы могут быть исключены из Jar.
Однако я сам несколько раз обдумывал эту проблему и подумал, что я сам смог ее решить. Все, что для этого потребуется, - это проанализировать операторы импорта исходных файлов Java и построить график зависимости того, как классы взаимодействуют друг с другом. Каждая ссылка из основного класса должна рекурсивно сканироваться до тех пор, пока не будет собран полный граф. Затем, после того как граф собран, это будет случай вывода его таким способом, который могла бы обработать некоторая логика упаковки (или, если вы чувствуете смелость, JDK имеет свой собственный встроенный в Jar код создания / изменения, чтобы сделать это самостоятельно). Конечно, этот подход потребует написания этой пользовательской утилиты, а также пропустит полные ссылки на классы в коде.