diff --git a/dist/tools/doccheck/check.sh b/dist/tools/doccheck/check.sh
index 831b494dc0dcde944244ddf08bc9efa48c70b620..795c8b239fae77e39a5b7f1e587e48a904d31704 100755
--- a/dist/tools/doccheck/check.sh
+++ b/dist/tools/doccheck/check.sh
@@ -1,6 +1,8 @@
-#!/bin/sh
+#!/usr/bin/env bash
 
 # Copyright 2014 Oliver Hahm <oliver.hahm@inria.fr>
+#           2018 Kaspar Schleiser <kaspar@schleiser.de>
+#           2018 Alexandre Abadie <alexandre.abadie@inria.fr>
 #
 # This file is subject to the terms and conditions of the GNU Lesser
 # General Public License v2.1. See the file LICENSE in the top level
@@ -8,15 +10,61 @@
 
 RIOTBASE=$(readlink -f "$(dirname $(realpath $0))/../../..")
 
+if tput colors &> /dev/null && [ $(tput colors) -ge 8 ]; then
+    CERROR="\e[1;31m"
+    CWARN="\033[1;33m"
+    CRESET="\e[0m"
+else
+    CERROR=
+    CWARN=
+    CRESET=
+fi
+
 ERRORS=$(make -C "${RIOTBASE}" doc 2>&1 | \
             grep '.*warning' | \
             sed "s#${PWD}/\([^:]*\)#\1#g")
 
 if [ -n "${ERRORS}" ]
 then
-    echo "ERROR: Doxygen generates the following warnings:"
+    echo -e "${CERROR}ERROR: Doxygen generates the following warnings:${CRESET}"
     echo "${ERRORS}"
     exit 2
-else
-    exit 0
+fi
+
+exclude_filter() {
+    grep -v -e vendor -e examples -e tests
+}
+
+# Check all groups are defined
+DEFINED_GROUPS=$(git grep @defgroup -- '*.h' '*.c' '*.txt' | \
+                    exclude_filter | \
+                    grep -oE '@defgroup[ ]+[^ ]+' | \
+                    grep -oE '[^ ]+$' | sort -u)
+
+UNDEFINED_GROUPS=$( \
+    for group in $(git grep '@ingroup' -- '*.h' '*.c' '*.txt' | \
+                    exclude_filter | \
+                    grep -oE '[^ ]+$' | sort -u); \
+    do \
+        echo "${DEFINED_GROUPS}" | grep -xq "${group}" || echo "${group}"; \
+    done \
+    )
+
+ALL_RAW_INGROUP=$(git grep '@ingroup' -- '*.h' '*.c' '*.txt' | exclude_filter)
+
+UNDEFINED_GROUPS_PRINT=$( \
+    for group in ${UNDEFINED_GROUPS}; \
+    do \
+        echo -e "\n${CWARN}${group}${CRESET} found in:"; \
+        echo "${ALL_RAW_INGROUP}" | grep "\<${group}\>$" | sort -u | \
+                awk -F: '{ print "\t" $1 }'; \
+    done \
+    )
+
+if [ -n "${UNDEFINED_GROUPS}" ]
+then
+    COUNT=$(echo "${UNDEFINED_GROUPS}" | wc -l)
+    echo -ne "${CWARN}WARNING${CRESET} "
+    echo -e "There are ${CWARN}${COUNT}${CRESET} undefined Doxygen groups:"
+    echo "${UNDEFINED_GROUPS_PRINT}"
 fi