Finding customer searches and graphing their items
Regarding performance the code looks fine. Possibly you are missing useful indexes.

As far as the code itself is concerned I have the following observations.

Remove three part names. 

[DB].[dbo].[SearchHistory] and [DB].[dbo].[CustomerExclusions]

It is common to want to run queries against different versions of the database. Hardcoding the database name in to SQL makes this harder.

If this SQL lives inside a stored proc in a copy of the database DB_copy on the same instance as DB you may be unaware that this is, in fact, referencing a different database for some time. Similarly if the SQL is sent by an application it is likely that most people will assume that changing the "Initial Catalogue" in the connection string will change the tables being queried.

Add table aliases and use them for all columns in the correlated sub query 

/*Original Code*/
FROM [DB].[dbo].[SearchHistory] 
WHERE NOT EXISTS 
(
    SELECT 1 FROM [DB].[dbo].[CustomerExclusions]
    WHERE [CustomerNumber] = [SearchHistory].[CustomerNumber]
    AND [ExcludeFromSearch] = 1
)




/*Rewritten Code*/
FROM   dbo.SearchHistory sh
WHERE  NOT EXISTS (SELECT *
                   FROM   dbo.CustomerExclusions ce
                   WHERE  ce.CustomerNumber = sh.CustomerNumber
                          AND ce.ExcludeFromSearch = 1) 


If the table CustomerExclusions does not have any columns called CustomerNumber or ExcludeFromSearch but these do exist in SearchHistory then the original correlated sub query will resolve them from the outer scope giving you incorrect results rather than an error message. Using two part names as in the second example would give an error in that case as well as making the code more explicitly self documenting. I have also removed the square brackets as they are not required and I find them distracting. For reasons of personal preference I have replaced the 1 with a *. It makes no difference to the execution plan.

Other changes. 


I used a CTE to remove some of the repeated formulas scattered around the code.
I replaced your use of SUM()/COUNT(*) with AVG
It is only necessary to cast one of the operands to avoid integer division - not both.
I changed the column names returned by the query so they meet the rules for standard identifiers and don't need to be quoted.
I changed to the non standard column_alias = expression syntax as I find it makes the query easier to read when the select list contains long expressions.




WITH CTE
     AS (SELECT AtDateTime,
                /*Use CASE if &lt; SQL Server 2012*/
                IIF(NumFound = 0, 1, 0)       AS NoResults,
                DATENAME(WEEKDAY, AtDateTime) AS WeekDayName,
                DATEPART(WEEKDAY, AtDateTime) AS WeekDayNumber
         FROM   dbo.SearchHistory sh
         WHERE  NOT EXISTS (SELECT *
                            FROM   dbo.CustomerExclusions ce
                            WHERE  ce.CustomerNumber = sh.CustomerNumber
                                   AND ce.ExcludeFromSearch = 1))
SELECT WeekDayName,
       NumberOfSearches 
             = COUNT(*),
       AverageSearchesPerDay
             = COUNT(*) / CAST(COUNT(DISTINCT CONVERT(DATE, AtDateTime)) AS DECIMAL(10, 2)),
       NumberOfSearchesWithNoResults 
             = SUM(NoResults),
       PercentOfSearchesWithNoResults
             = CAST(AVG(CAST(NoResults AS DECIMAL(10, 2))) AS DECIMAL(10, 4))
FROM   CTE
GROUP  BY WeekDayNumber,
          WeekDayName
ORDER  BY WeekDayNumber