Here is how I would handle this, simply in the context of hitting the database less often. There are probably other improvements you could make as well, but that's not what you're asking for.
DateTime startDate = DateTime.Parse(start);
DateTime endDate = DateTime.Parse(end);
List<AlcoholForms> formsList = db.AlcoholForms.Where(x => x.CreatedDate >= startDate && x.CreatedDate <= endDate).ToList();
ViewData["TotalDuringPeriod"] = formsList.Count();
ViewData["TotalUniqueClientsDuringPeriod"] = formsList.Select(x => x.ClientId).Distinct().Count();
ViewData["TotalGateNew"] = formsList.Count(x => x.ReferredTo == "Gate" && x.Reengagement == false);
ViewData["TotalGateReengagment"] = formsList.Count(x => x.ReferredTo == "Gate" && x.Reengagement);
ViewData["TotalSwitchNew"] = formsList.Count(x => x.ReferredTo == "Switch" && x.Reengagement == false);
ViewData["TotalSwitchReengagement"] = formsList.Count(x => x.ReferredTo == "Switch" && x.Reengagement);
List<ReportAlcoholReferals> reportData = formsList.Where(x => x.Referral).Select(x => new ReportAlcoholReferals()
{
FirstName = x.Client.FirstName,
LastName = x.Client.LastName,
Date = x.CreatedDate,
ClientId = x.ClientId,
AlcoholForm = x
}).OrderBy(x => x.AlcoholForm.ReferredTo).ToList();
return View(reportData);
The list declaration for formsList means that the database will be queried once and store the results in the List object. From there, you can continue to use LINQ to break out your data.