jsprint fiddle

HTML

<script src="http://brigand.github.io/jsprint/build/output/jsprint.min.js"></script>
<div class="b">used twice</div>
<div class="b">used twice</div>
<div class="d">no css for .d</div>
<div>no class</div>

CSS

.a {
    display: block;
}
.b {
    display: block;
}
.b {
    display: inline;
}
#something.b {
    border: 1px solid black;
}

JavaScript

var styles = document.head.getElementsByTagName('style');
var css = styles[styles.length - 1].innerHTML;

var clean = css.replace(/\/\*.*?\*\//g, '').replace(/\{[^}]*\}/g, ',');
var re_class = /\.(\w+)/g;
var cssClasses = {}, match, c;
while (match = re_class.exec(clean)) {
    c = match[1];
    cssClasses[c] = cssClasses[c] + 1 || 1;
}

jsprint("css classes used", cssClasses);

var elements = document.body.getElementsByTagName("*");
var neverUsed = Object.keys(cssClasses);
var neverDefined = [];
var htmlClasses = {};
for (var i = 0; i < elements.length; i++) {
    var e = elements[i];
    var classes = (e.className || "").split(" ");

    // remove classes that were used
    for (var j = 0; j < classes.length; j++) {
        for (var k = 0; k < neverUsed.length; k++) {
            if (neverUsed[k] === classes[j]) {
                neverUsed.splice(k, 1);
            }
        }

        // and check if the class exists in css
        if (classes[j].length && cssClasses[classes[j]] == null) {
            neverDefined.push(classes[j]);
        }
            if (classes[j].length) {
                htmlClasses[classes[j]] = htmlClasses[classes[j]] + 1 || 1;
            }
    }
}

jsprint("html class usage", htmlClasses);
jsprint("never used in HTML", neverUsed);
jsprint("never defined in CSS", neverDefined);