I solved this with the Jinja test "exists" and the select filter to filter away the resulting 'AnsibleUndefined' values. The "is exists" test checks if the path exists on the host were the Ansible code is executing on. This is the place the credentials are stored.

The solved code is below:

    ---
    - hosts: localhost
      tasks:
      - name: Include users.yaml and setup all vars for nexus
        include_vars:
          file: users.yaml
          name: users
      - set_fact:
          tmp_user:
          - username: "{{ item.username }}"
            first_name: "{{ item.first_name }}"
            last_name: "{{ item.last_name }}"
            email: "{{ item.email }}"
            password: "{{ lookup('password', 'credentials/' + item.username + '/password.txt length=15 chars=ascii_letters') }}"
            roles: "{{ item.roles }}"
        loop: "{{ users.nexus_local_users }}"
        register: tmp_users
        when: "not '{{ playbook_dir }}/credentials/{{ item.username }}/password.txt' is exists"
      - set_fact:
          tmp_user: "{{ item.item | combine(item.item) }}"
        with_items: "{{ tmp_users.results }}"
        register: tmp_users
        when: "not item is skipped"
      - set_fact:
          nexus_local_users: "{{ tmp_users.results | map(attribute='ansible_facts.tmp_user') | list | select('defined') | list }}"
      - debug:
          msg: "{{ nexus_local_users }}"

The following was added/changed:

        when: "not '{{ playbook_dir }}/credentials/{{ item.username }}/password.txt' is exists"

-

          nexus_local_users: "{{ tmp_users.results | map(attribute='ansible_facts.tmp_user') | list | select('defined') | list }}"

This makes for a compact solution without adding more tasks/files.

For more information see: https://docs.ansible.com/ansible/latest/user_guide/playbooks_tests.html