git branch --merged main | grep -vE '^\*|main|master' | xargs -r git branch -d
--merged main lists the branches whose commits are all in main, the grep protects the current branch and the main ones, and -d only deletes merged branches anyway, so it's doubly safe.
Run the first half alone to see the list before you add the xargs.
Branches squash-merged through a pull request don't show as merged, because their commits aren't in main. Those you still delete by hand, with -D.