diff --git a/diceware/wordlist.py b/diceware/wordlist.py
index 246b5fb4ed11877c030cfd86374f22ded4de9d8e..787cfc4d614d0c51c1b5e896c9bc2677cd1ac121 100644
--- a/diceware/wordlist.py
+++ b/diceware/wordlist.py
@@ -39,6 +39,37 @@ RE_VALID_WORDLIST_FILENAME = re.compile(
     r'^wordlist_([\w-]+)\.[\w][\w\.]+[\w]+$')
 
 
+def get_wordlist_dirs():
+    """Get the directories in which wordlists can be stored.
+
+    We look into the following dirs (in that order):
+        (1) Local `wordlists` dir (part of install)
+        (2a) ${XDG_DATA_HOME}/diceware/      (if $XDG_DATA_HOME is defined)
+        (2b) ${HOME}/.local/share/diceware/  (else)
+        (3a) `<DIR>/diceware/` for each <DIR> in ${XDG_DATA_DIRS}
+             (if ${XDG_DATA_DIRS} is defined)
+        (3b) /usr/local/share/diceware/, /usr/share/diceware/
+             (else)
+    """
+    xdg_data_dirs = os.getenv("XDG_DATA_DIRS")
+    if not xdg_data_dirs:  # unset or empty string
+        xdg_data_dirs = "/usr/local/share:/usr/share"
+    user_home = os.path.expanduser("~")
+    xdg_data_home = os.getenv("XDG_DATA_HOME", "")
+    if (xdg_data_home == "") and (user_home != "~"):
+        xdg_data_home = os.path.join(user_home, ".local", "share")
+    if xdg_data_home:
+        xdg_data_dirs = "%s:%s" % (xdg_data_home, xdg_data_dirs)
+    local_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), "wordlists"))
+    result = [local_dir] + list(
+        [
+            os.path.join(os.path.abspath(path), "diceware")
+            for path in xdg_data_dirs.split(":")
+        ]
+    )
+    return result
+
+
 def get_wordlists_dir():
     """Get the directory in which word lists are stored.
     """
@@ -50,15 +81,18 @@ def get_wordlist_names():
     """Get a all names of wordlists stored locally.
     """
     result = []
-    wordlists_dir = get_wordlists_dir()
-    filenames = os.listdir(wordlists_dir)
-    for filename in filenames:
-        if not os.path.isfile(os.path.join(wordlists_dir, filename)):
-            continue
-        match = RE_VALID_WORDLIST_FILENAME.match(filename)
-        if not match:
+    # wordlists_dir = get_wordlists_dir()
+    for wordlists_dir in get_wordlist_dirs():
+        if not os.path.isdir(wordlists_dir):
             continue
-        result.append(match.groups()[0])
+        filenames = os.listdir(wordlists_dir)
+        for filename in filenames:
+            if not os.path.isfile(os.path.join(wordlists_dir, filename)):
+                continue
+            match = RE_VALID_WORDLIST_FILENAME.match(filename)
+            if not match:
+                continue
+            result.append(match.groups()[0])
     return sorted(result)
 
 
@@ -74,13 +108,15 @@ def get_wordlist_path(name):
     """
     if not RE_WORDLIST_NAME.match(name):
         raise ValueError("Not a valid wordlist name: %s" % name)
-    wordlists_dir = get_wordlists_dir()
-    for filename in os.listdir(wordlists_dir):
-        if not os.path.isfile(os.path.join(wordlists_dir, filename)):
+    for wordlists_dir in get_wordlist_dirs():
+        if not os.path.isdir(wordlists_dir):
             continue
-        match = RE_VALID_WORDLIST_FILENAME.match(filename)
-        if match and match.groups()[0] == name:
-            return os.path.join(wordlists_dir, filename)
+        for filename in os.listdir(wordlists_dir):
+            if not os.path.isfile(os.path.join(wordlists_dir, filename)):
+                continue
+            match = RE_VALID_WORDLIST_FILENAME.match(filename)
+            if match and match.groups()[0] == name:
+                return os.path.join(wordlists_dir, filename)
 
 
 class WordList(object):
diff --git a/tests/conftest.py b/tests/conftest.py
index d9c7fb60608668c8f18b94aca9d1f74d25ccb5d5..7df11236902ca2eb7a2ddf65ff95d603c4422222 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -56,7 +56,7 @@ def wordlists_dir(request, monkeypatch, tmpdir):
     """This fixture provides a temporary wordlist dir.
     """
     monkeypatch.setattr(
-            "diceware.wordlist.get_wordlists_dir", lambda: str(tmpdir))
+        "diceware.wordlist.get_wordlist_dirs", lambda: [str(tmpdir)])
     return tmpdir
 
 
@@ -85,6 +85,8 @@ def change_home(monkeypatch, tmpdir):
     monkeypatch.setenv("HOME", str(tmpdir))
     monkeypatch.delenv("XDG_CONFIG_DIRS", raising=False)
     monkeypatch.delenv("XDG_CONFIG_HOME", raising=False)
+    monkeypatch.delenv("XDG_DATA_DIRS", raising=False)
+    monkeypatch.delenv("XDG_DATA_HOME", raising=False)
     return tmpdir
 
 
diff --git a/tests/test_wordlist.py b/tests/test_wordlist.py
index 6dd5578b706b6a823cc2624c43bf1b8d1019bca6..14c23573ccdac98f213991a3a8d39077b4bc3222 100644
--- a/tests/test_wordlist.py
+++ b/tests/test_wordlist.py
@@ -4,9 +4,9 @@ import pytest
 import sys
 from io import StringIO
 from diceware.wordlist import (
-    get_wordlists_dir, RE_WORDLIST_NAME, RE_NUMBERED_WORDLIST_ENTRY,
-    RE_VALID_WORDLIST_FILENAME, get_wordlist_path, get_wordlist_names,
-    WordList,
+    get_wordlist_dirs, get_wordlists_dir, RE_WORDLIST_NAME,
+    RE_NUMBERED_WORDLIST_ENTRY, RE_VALID_WORDLIST_FILENAME, get_wordlist_path,
+    get_wordlist_names, WordList,
 )
 
 
@@ -22,6 +22,32 @@ def wordlist(request, tmpdir):
 
 class TestWordlistModule(object):
 
+    def test_get_wordlist_dirs(self, home_dir):
+        # We can get a list of valid wordlist dirs even w/o home
+        mydir = os.path.abspath(os.path.dirname(__file__))
+        local_wlist_dir = os.path.join(os.path.dirname(mydir), "diceware", "wordlists")
+        assert get_wordlist_dirs() == [
+            local_wlist_dir,
+            str(home_dir / ".local" / "share" / "diceware"),
+            "/usr/local/share/diceware",
+            "/usr/share/diceware",
+        ]
+
+    def test_get_wordlist_dirs_considers_xdg_data_home(self, home_dir, monkeypatch):
+        # We consider $XDG_DATA_HOME when determining dirs
+        monkeypatch.setenv("XDG_DATA_HOME", str(home_dir))
+        wlists = get_wordlist_dirs()
+        assert str(home_dir / "diceware") in wlists
+        assert str(home_dir / ".local" / "share" / "diceware") not in wlists
+
+    def test_get_wordlist_dirs_considers_xdg_data_dirs(self, home_dir, monkeypatch):
+        # We consider $XDG_DATA_DIRS when determining dirs
+        monkeypatch.setenv("XDG_DATA_DIRS", "/foo:/bar")
+        wlists = get_wordlist_dirs()
+        assert "/usr/share/diceware" not in wlists
+        assert "/foo/diceware" == wlists[-2]
+        assert "/bar/diceware" == wlists[-1]
+
     def test_re_wordlist_name(self):
         # RE_WORDLIST_NAME really works
         # valid stuff
@@ -129,6 +155,15 @@ class TestWordlistModule(object):
         assert exc_info.value.args[0].startswith(
             'Not a valid wordlist name')
 
+    def test_get_wordlist_path_copes_w_nonexistant_dirs(self, wordlists_dir, monkeypatch):
+        path1 = wordlists_dir.join("wordlist_foo.txt")
+        path1.write("foo\n")
+        assert get_wordlist_path("foo") == path1
+        # now we remove the wordlist and its path
+        path1.remove()
+        wordlists_dir.remove()
+        assert get_wordlist_path("foo") is None
+
     def test_get_wordlist_names(self, wordlists_dir):
         # we can get wordlist names also if directory is empty.
         wlist_path = wordlists_dir.join('wordlist_my_en.txt')