Assuming GNU find and the bash shell (as is used in the question), this is a short script that would accomplish what you're trying to do:
#!/bin/bash
IFS=:
set -f
args=( -false )
for dirpath in $PATH; do
args+=( -o -path "$dirpath" )
done
find / \( \( "${args[@]}" \) -o \
\( -type d \( ! -executable -o ! -readable \) \) \) -prune -o \
-type f -executable -exec file {} +
This first creates the array args, consisting of dynamically constructed arguments to find. It does this by splitting the value of $PATH on colons, the value that we've given to the IFS variable. The splitting is happening when we use $PATH unquoted in the loop header.
Ordinarily, the shell would invoke filename globbing on each of the words generated from the splitting of $PATH, but I'm using set -f to turn off filename globbing, just in case any of the directory paths in $PATH contains globbing characters (these would still be problematic as the -path operand of find would interpret them as patterns).
If my PATH variable contains the string
/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin
then args will be the following list (each line here is a separate element in the array, this is not really a set of strings with newline characters in-between them):
-false
-o
-path
/usr/bin
-o
-path
/bin
-o
-path
/usr/sbin
-o
-path
/sbin
-o
-path
/usr/X11R6/bin
-o
-path
/usr/local/bin
-o
-path
/usr/local/sbin
This list is slotted into the find command invocation, in parentheses. There is no need to repeat -prune for each and every directory, as you could just use it once as I have above.
I've opted for pruning any non-executable or non-readable directory. This ought to get rid of a lot of permission errors for directories that you can't access or list the contents of. Would you want to simplify the find command by removing this bit, use
find / \( "${args[@]}" \) -prune -o \
-type f -executable -exec file {} +
Also, I'm running file on the found pathnames in batches, rather than once per pathname.