Disclaimer: I'm the current author of the rawhide (rh(1)) program referred to in this response (at github/raforg).
TL;DR Just scroll to the end
If you are only looking for actual shell scripts, which are executable, this rawhide (rh(1)) command will do it faster than find(1) plus a separate file(1) process for each candidate (because it doesn't require any file(1) processes, or grep(1), or awk(1)):
rh 'f && ix && ("text/plain*".mime || "*sh*script*".what)'
It lists regular files that are executable, whose mimetype starts with text/plain, or whose file(1) output would contain "sh script" or "shell script".
It handles very plain shell scripts with no #!/bin/sh line (on the understanding that any text file with no #! line that is executable is treated by the operating system as a /bin/sh script when it is executed), and it handles shell scripts with #!/bin/sh or #!/bin/ksh or #!/bin/zsh etc., and it handles shell scripts with #!/usr/bin/env zsh etc.
It can be made faster by limiting the expensive analysis (I/O) just to files below a certain size by adding "&& sz<50K" immediately after the "&& ix" (for the find(1) version, add "-size -50k" before "-exec"). That will eliminate I/O on files that are too large to be shell scripts. How large is too large? You decide. I've got one that's 63KiB!
If you need to include non-executable files that are sourced into a shell script (i.e., shell fragments), I don't know what to do. file(1) (and rh(1)) see them as text/plain and ASCII text (at least on macOS and Linux). I could recommend making all shell fragments executable, but that would be cheating. 
The find(1) command at the top of this discussion doesn't report non-executable shell fragments either (for me). In fact, it doesn't report a lot of things. My test cases had:
1 no #! line and not executable [therefore not a shell script]
2 no #! line but executable
3 #!/bin/sh
4 #!/bin/ksh
5 #!/bin/zsh
6 #!/bin/bash
7 #!/usr/bin/env ksh
8 #!/usr/bin/env zsh
9 #!/usr/bin/env bash
This rh(1) command listed all but #1. The find(1) command at the top of this discussion only reported #3 #4 #6 and #9. It missed #2 because it had no #! line. It missed #5 because the file(1) output contained "zsh script" rather than "shell script". It missed #7 and #8 because the file(1) output contained "/usr/bin/env ksh script" and "/usr/bin/env zsh script" (i.e., file(1) just quoted the #! line), but it did report #9 because file(1) detects "/usr/bin/env bash" as a special case.
To include scripts in other languages like perl, python, js, etc., it's slightly simpler:
rh 'f && ix && ("text/plain*".mime || "*script*".what)'
Unfortunately, the following isn't as good (it doesn't report scripts without a #! line):
rh 'f && ix && "*script*".what'
But that might be enough for your needs, if all of your scripts have a #! line.
Here are the find(1) equivalents (different on Linux and macOS) of the less good version (that misses scripts without a #! line).
GNU/Linux version:
find . -type f -perm /111 -exec file '{}' ';' | awk -F: '/script/ { print $1 }'
macOS version:
find . -type f -perm +111 -exec file '{}' ';' | awk -F: '/script/ { print $1 }'
Here are the find(1) equivalents of the complete version (that does detect shell scripts without a #! line):
GNU/Linux version:
find . -type f -perm /111 -exec /bin/sh -c '(file --mime-type "{}"; file "{}") | grep -Eq "text/plain|script"' ';' -print
macOS version:
find . -type f -perm +111 -exec /bin/sh -c '(file --mime-type "{}"; file "{}") | grep -Eq "text/plain|script"' ';' -print
The find(1) command at the start of this discussion does detect non-executable shell fragments if they start with #!/bin/sh, but that #! line is non-functional. Without the execute bit, the kernel will never use it to execute the file. It can only be a shell fragment, and the #! line is probably there for syntax-highlighting purposes in a text editor, rather than for execution. But if your non-executable shell fragments do have a #! line for syntax-highlighting purposes, they can be included with this command:
rh 'f && ("*script*".what || ix && "text/plain*".mime)'
If you're happy to exclude actual executable shell scripts without a #! line, this will do:
rh 'f && "*script*".what'
To limit it to just shell scripts (i.e., no perl, python, etc.):
rh 'f && "*sh*script*".what'
These super short versions aren't the most accurate, but they're probably fine.