Os pipes criam subshells e essas subshells não podem alterar os valores nos processos acima deles. Experimente:
while read window; do
WINS=( ${WINS[@]} $window )
echo "Found window: $window; New size: ${#WINS[@]}"
done < <(wmctrl -l | grep -Ev " (${SKIP})" | cut -d \ -f 1)