I run a couple of Umbraco sites and as usual after a couple of years some sites tend to become a bit dirty. The cleaning could be 100 % automated but thats to risky business for me but having some visual help in Template and Document Type usage was welcome. So by the help of uComponents uQuery I made some outputs.
Where you put the code is up to you, I did put it in an ascx file and run it as a macro.
Usings
using System;
using System.Collections.Generic;
using System.Linq;
using uComponents.Core;
using umbraco.cms.businesslogic.template;
using umbraco.cms.businesslogic.web;
using umbraco.interfaces;
using umbraco.NodeFactory;
The Code
/// <summary>
/// Invoke this method...
/// </summary>
private void WhatsUp()
{
// Start at root level (-1) and populate the AllNodes property
GetAllNodesAsFlatList(new Node(-1));
PrintResultInfo("Templates", GetTemplateResult());
PrintResultInfo("Document Types", GetDocTypeInfo());
}
/// <summary>
/// Return alias and occurences of all templates
/// </summary>
/// <returns></returns>
private List<Result> GetTemplateResult()
{
return
Template.GetAllAsList().Select(
template =>
new Result {Alias = template.Alias, Count = AllNodes.Count(x => x.template.Equals(template.Id))}).
ToList();
}
/// <summary>
/// Return alias and occurences of all document types
/// </summary>
/// <returns></returns>
private List<Result> GetDocTypeInfo()
{
return
DocumentType.GetAllAsList().Select(
documentType =>
new Result() { Count = GetNodesByNodeType(documentType.Id), Alias = documentType.Alias }).ToList();
}
private int GetNodesByNodeType(int documentType)
{
var nodes = uQuery.GetNodesByType(documentType);
if (nodes == null)
return 0;
return nodes.Count;
}
/// <summary>
/// Print the result info
/// </summary>
/// <param name="header"></param>
/// <param name="results"></param>
private void PrintResultInfo(string header, List<Result> results)
{
Response.Write(string.Format("<h1>{0}</h1>", header));
Response.Write("<h2>Empty</h2>");
foreach (Result result in results.Where(x => x.Count.Equals(0)))
{
Response.Write(string.Format("{0} [{1}]<br />", result.Alias, result.Count));
}
Response.Write("<h2>Used</h2>");
foreach (Result result in results.Where(x => !x.Count.Equals(0)))
{
Response.Write(string.Format("{0} [{1}]<br />", result.Alias, result.Count));
}
}
/// <summary>
/// Storage for GetAllNodesAsFlatList
/// </summary>
private readonly List<INode> AllNodes = new List<INode>();
/// <summary>
/// Get all child nodes from a certain node
/// </summary>
/// <param name="startNode"></param>
private void GetAllNodesAsFlatList(INode startNode)
{
AllNodes.Add(startNode);
// Traverse the above throug the node
List<INode> children = startNode.ChildrenAsList;
if (!children.Any())
return;
foreach (INode child in children)
{
GetAllNodesAsFlatList(child);
}
}
/// <summary>
/// Result object
/// </summary>
private class Result
{
public int Count { get; set; }
public string Alias { get; set; }
}
The result
I did truncate the result to max 5 posts, the actual result was hundreds of lines 
The result shows empty and used as groups with the alias and number of nodes that are using the Document Type or Template.

Thats it!
Cheers